/*
*  Mesh.cpp
*  SypXIPhone
*
*  Created by Luv Khemani on 5/13/10.
*  Copyright 2010 Luv Khemani. All rights reserved.
*
*/


#define _USE_MATH_DEFINES
#include <math.h>
#include <sstream>

#ifdef SYPX_MEMCHECK
#include "mmgr.h"
#endif

#include "Mesh.h"


namespace SypX
{
	Mesh::Mesh():hasColor(false), primType(TRIANGLES)
	{

	}
	Mesh::~Mesh()
	{

	}

	void Mesh::setPrimitiveType(PrimitiveType type)
	{
		primType = type;
	}

	PrimitiveType Mesh::getPrimitiveType()
	{
		return primType;
	}

	FloatArray& Mesh::getDataArrayRef()
	{
		return data;
	}

	UShort Mesh::getNumVertices() const
	{		
		if(stride)
		{
			return data.size()/ (stride / sizeof(float));
		}
		else
		{//only stores position, so likely to be 3 floats for XYZ
			return data.size()/3;		
		}
	}

	UByte Mesh::getStride()
	{
		return stride;
	}

	void Mesh::setStride(UByte s)
	{
		stride = s;
	}

	bool Mesh::usesColor()
	{
		return hasColor;
	}

	void Mesh::resizeQuad(float width, float height)
	{
		assert(data.size() > 0 && "Mesh has not been init or has no vertices to resize");
		if(!hasColor)
		{
			float hw = width/2.0f;
			float hh = height/2.0f;

			data[0] = -hw;
			data[1] = hh;

			data[5] = -hw;
			data[6] = -hh;

			data[10] = hw;
			data[11] = -hh;

			data[15] = hw;
			data[16] = hh;

			data[20] = -hw;
			data[21] = hh;

			data[25] = hw;
			data[26] = -hh;

		}
	}

	void Mesh::initAsQuad(float width, float height, float depth, bool genColor)
	{
		float hw = width/2.0f;
		float hh = height/2.0f;

		hasColor = genColor;

		data.push_back(-hw);
		data.push_back(hh);
		data.push_back(depth);//top left
		data.push_back(0.0f);
		data.push_back(1.0f);
		if(genColor)
		{//add RGB
			data.push_back(1.0f);
			data.push_back(1.0f);
			data.push_back(1.0f);
		}

		data.push_back(-hw);
		data.push_back(-hh);
		data.push_back(depth);//btm left
		data.push_back(0.0f);
		data.push_back(0.0f);
		if(genColor)
		{//add RGB
			data.push_back(1.0f);
			data.push_back(1.0f);
			data.push_back(1.0f);
		}

		data.push_back(hw);
		data.push_back(-hh);
		data.push_back(depth);//btm right
		data.push_back(1.0f);
		data.push_back(0);
		if(genColor)
		{//add RGB
			data.push_back(1.0f);
			data.push_back(1.0f);
			data.push_back(1.0f);
		}

		data.push_back(hw);
		data.push_back(hh);
		data.push_back(depth);//top right
		data.push_back(1.0f);
		data.push_back(1.0f);
		if(genColor)
		{//add RGB
			data.push_back(1.0f);
			data.push_back(1.0f);
			data.push_back(1.0f);
		}

		data.push_back(-hw);
		data.push_back(hh);
		data.push_back(depth);//top left
		data.push_back(0.0f);
		data.push_back(1.0f);
		if(genColor)
		{//add RGB
			data.push_back(1.0f);
			data.push_back(1.0f);
			data.push_back(1.0f);
		}

		data.push_back(hw);
		data.push_back(-hh);
		data.push_back(depth);//btm right
		data.push_back(1.0f);
		data.push_back(0);
		if(genColor)
		{//add RGB
			data.push_back(1.0f);
			data.push_back(1.0f);
			data.push_back(1.0f);
		}

		MeshPart mp;
		mp.count = 6;	//6 vertices
		parts.push_back(mp);
		if(genColor)
		{
			stride = 32;
		}
		else
		{
			stride = 20;
		}

		std::ostringstream oss;
		oss<<"Quad"<<getUniqueID();
		setFileName(oss.str());

	}

	void Mesh::initAsCircle(float radius, int smoothness, float depth, bool genColor)
	{	
		float currX = radius, currY = 0;
		float prevX, prevY;

		if (smoothness < 1)
			smoothness = 1;

		for (int i = 0; i <= smoothness; i++) {

			float angle = static_cast<float>(((float) i / smoothness) * 2 * M_PI);

			prevX = currX;
			prevY = currY;

			currX = radius * cos(angle);
			currY = radius * sin(angle);

			// top edge
			data.push_back(prevX);
			data.push_back(prevY);
			data.push_back(depth);
			data.push_back(0);
			data.push_back(0);
			if(genColor)
			{//add RGB
				data.push_back(1.0f);
				data.push_back(1.0f);
				data.push_back(1.0f);
			}

			// bottom edge
			data.push_back(currX);
			data.push_back(currY);
			data.push_back(depth);
			data.push_back(0);
			data.push_back(0);
			if(genColor)
			{//add RGB
				data.push_back(1.0f);
				data.push_back(1.0f);
				data.push_back(1.0f);
			}

			// center
			data.push_back(0);
			data.push_back(0);
			data.push_back(depth);
			data.push_back(0);
			data.push_back(0);
			if(genColor)
			{//add RGB
				data.push_back(1.0f);
				data.push_back(1.0f);
				data.push_back(1.0f);
			}
		}		

		MeshPart mp;
		mp.count = 3 * smoothness;
		parts.push_back(mp);
		if(genColor)
		{
			stride = 32;
		}
		else
		{
			stride = 20;
		}

		std::ostringstream oss;
		oss<<"Circle"<<getUniqueID();
		setFileName(oss.str());

	}
}